#ifndef ACAPELLA_SYNCHRONIZE_MUTEX_COND_LINUX_HPP
#define ACAPELLA_SYNCHRONIZE_MUTEX_COND_LINUX_HPP

#include <pthread.h>
#include <time.h>
#include <sys/time.h>

namespace acapella
{
namespace synchronize
{

class mutex_cond
{
public:
	mutex_cond()
	{
		pthread_mutex_init(&mutex_, NULL);
		pthread_cond_init(&cond_, NULL);
	}

	~mutex_cond()
	{
		pthread_cond_destroy(&cond_);
		pthread_mutex_destroy(&mutex_);
    }

    int wait()
    {
        return pthread_cond_wait(&cond_, &mutex_);
    }

	int wait(_uint32_ timeout)
	{
		timespec tsp;
		maketimeout(&tsp, timeout);

		return pthread_cond_timedwait(&cond_, &mutex_, &tsp); 
	}

	int signal()
	{
		return pthread_cond_signal(&cond_);
	}

	int boardcast()
	{
		return pthread_cond_broadcast(&cond_);
	}

	void maketimeout(struct timespec *tsp, _uint32_ msTimeout)
	{
		struct timeval now;
		gettimeofday(&now, NULL); 

		tsp->tv_sec = now.tv_usec + (msTimeout / 1000);
		tsp->tv_nsec = now.tv_usec * 1000 + ((msTimeout % 1000) * 1000);

		return;
	}

private:
	pthread_mutex_t mutex_; 
	pthread_cond_t cond_;

	mutex_cond(const mutex_cond&);
	mutex_cond& operator=(const mutex_cond&);
};

}
}



#endif
